﻿/**
 *    Copyright 2012 Yohan Courbe
 *
 *  Licensed under the Apache License, Version 2.0 (the "License") 
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *  
 *      http://www.apache.org/licenses/LICENSE-2.0
 *      
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

using System;
using System.Globalization;
using System.Windows.Forms;
using System.Threading;
using NetworkAnalyzer.SQL;
using SharpPcap;

namespace NetworkAnalyzer
{
    public partial class ProgramGUI : Form
    {
        private static NetworkAnalyzer _networkAnalyzer;
        private static bool _networkAnalyzerIsRunning = false;
        private static ProgramGUI _programInstance;
        private static bool _updateStatisticsThreadControl;
        private static Thread _updateStatisticsThread = new Thread(UpdateStatisticsThread);
        
        public ProgramGUI()
        {
            InitializeComponent();
            _programInstance = this;
            CheckForIllegalCrossThreadCalls = false;
        }

        private void ProgramGuiLoad(object sender, EventArgs e)
        {
            if (CaptureDeviceList.Instance.Count < 1)
            {
                AddEventMessage("Any devices detected. Impossible to start a capture");
            }
            else
            {
                foreach (var device in CaptureDeviceList.Instance)
                {
                    AddConsoleEventMessage(String.Format("Device found {0}", device.Name));
                    var networkDevice = new NetworkDevice(device);
                    InterfacesComboBox.Items.Add(networkDevice); 
                }

                InterfacesComboBox.Enabled = true;
                try{_networkAnalyzer = new NetworkAnalyzer();}
                catch(Exception ex){Console.WriteLine(ex);}

                AddEventMessage("Testing database connection");

                AddEventMessage(MysqlDatabaseConnection.TestConnection() == 0
                                    ? "Success"
                                    : "Fail. Can't connect to the database.");
            }

            textBoxCidr.Text = Properties.Settings.Default.app_last_cidr;
        }

        private void AddEventMessage(string message)
        {
            EventsTextBox.AppendText(String.Format("[{0}] {1}\n", DateTime.Now, message));
        }

        private void AddConsoleEventMessage(string message)
        {
            Console.WriteLine(message);
        }

        private void StartButtonClick(object sender, EventArgs e)
        {
            if (_networkAnalyzerIsRunning)
            {
                // Send message
                AddEventMessage("Stopping capture analyzing");

                // Update GUI
                StartButton.Text = "Start";
                InterfacesComboBox.Enabled = true;
                textBoxCidr.Enabled = true;

                // Stop Analyzer
                _networkAnalyzer.Stop();
                _networkAnalyzerIsRunning = false;

                // Stop GUIupdater thread
                _updateStatisticsThreadControl = false;

                // Send message
                AddEventMessage("Stopped");
            }
            else        // Start Analyzer
            {
                try
                {
                    // Send message
                    AddEventMessage("Starting capture analyzing");

                    if (textBoxCidr.Text.Equals(String.Empty))
                    {
                        MessageBox.Show("A CIDR filter must be specified", "Error", MessageBoxButtons.OK,
                                        MessageBoxIcon.Error);
                        return;
                    }

                    Properties.Settings.Default.app_last_cidr = textBoxCidr.Text;
                    Properties.Settings.Default.Save();

                    // Start Analyzer
                    _networkAnalyzer.Start(((NetworkDevice)InterfacesComboBox.SelectedItem).CaptureDevice, textBoxCidr.Text);

                    // Start GUIupdater thread
                    _updateStatisticsThread.Start();
                    _updateStatisticsThreadControl = true;

                    // Update GUI
                    StartButton.Text = "Stop";
                    startedAtValueLabel.Text = DateTime.Now.ToString(CultureInfo.InvariantCulture);
                    InterfacesComboBox.Enabled = false;
                    textBoxCidr.Enabled = false;
                    _networkAnalyzerIsRunning = true;

                    // Send message
                    AddEventMessage("Started");
                }
                catch (Exception ex)
                {
                    AddEventMessage(String.Format("Error: {0}", ex.Message));
                    AddConsoleEventMessage(ex.StackTrace);
                }
            }
        }

        private static void UpdateStatisticsThread()
        {
            while (_updateStatisticsThreadControl)
            {
                if (_networkAnalyzerIsRunning)
                {
                    _programInstance.packetAnalyzedValueLabel.Text = String.Format("{0}", NetworkAnalyzer.PacketAnalyzed);
                    _programInstance.packetCapturedValueLabel.Text = String.Format("{0}", NetworkAnalyzer.PacketCaptured);

                    Thread.Sleep(1000);
                }
            }
        }

        private void InterfacesComboBoxSelectedIndexChanged(object sender, EventArgs e)
        {
            StartButton.Enabled = true;
            var selectedItem = (NetworkDevice)InterfacesComboBox.SelectedItem;

            _interfaceDeviceNameLabel.Text = selectedItem.Name;
            _interfaceDeviceIPAdressLabel.Text = selectedItem.IPAddress.ToString();
            _interfaceDeviceNetMaskLabel.Text = selectedItem.Netmask.ToString();
            _interfaceDeviceGatewayAddress.Text = selectedItem.GatewayAddress.ToString();
        }

        private void ProgramGuiFormClosed(object sender, FormClosedEventArgs e)
        {
            Application.Exit();
        }

        private void HttpHitsCloudToolStripMenuItemClick(object sender, EventArgs e)
        {
            new Engines.Graphics.HttpHits.GraphicsHttpHitsForm().Show();
        }

        private void RadarToolStripMenuItemClick(object sender, EventArgs e)
        {
            new Engines.Graphics.Radar.GraphicsRadarForm().Show();
        }

        private void DatabaseAutoConfigToolStripMenuItemClick(object sender, EventArgs e)
        {
            new MysqlConfigForm(this).Show();
        }
    }
}
